module tb_add_vector();

   logic [63:0] op_abs;
   logic [63:0] op_a;
   logic [3:0] 	mode;
   abs_vector #(.width(64), .granu(8)) U_abs_vector (
													  // Outputs
													 .o_abs			(op_abs),
													 // Inputs
													 .i_a				(op_a),
													 .i_mode			(mode) );


   initial
   	 begin
		logic [63:0] correct_result;
		
		for(int i=0;i<4;i++)
		  begin
			 $display("=============== test %d-bit mode ===============", (2**i)*8 );
			 for(int loop=0;loop<10000;loop++)
			   begin
				  mode = 1 << i;
				  op_a = {$random, $random};
				  for(int j=0;j<8/(2**i);j++)
					begin
					   // correct_result[(2**i)*8*j+(2**i)*8:(2**i)*8*j] = abs(op_a[(2**i)*8*j+(2**i)*8:(2**i)*8*j]);
					   // correct_result[(2**i)*8*j+(2**i)*8:(2**i)*8*j] = abs(op_a[(2**i)*8*j+(2**i)*8:(2**i)*8*j]);
					   if((2**i)*8 == 64)
						 begin
							// correct_result[64*j+:64] = $abs(op_a[64*j+:64]);
							// correct_result[64*j+:64] = op_a[64*j+:64][63] ? ~op_a[64*j+:64]+1 : op_a[64*j+:64];
							correct_result[63:0] = op_a[63] ? ~op_a[63:0]+1 : op_a[63:0];
						 end
					   if((2**i)*8 == 32)
						 begin
							correct_result[63:0] = { op_a[63] ? ~op_a[63:32]+1 : op_a[63:32], op_a[31] ? ~op_a[31:0]+1 : op_a[31:0] };
						 end
					   if((2**i)*8 == 16)
						 begin
							for(int k=0;k<4;k++)
							  begin
								 correct_result[k*16+:16] = op_a[(k+1)*16-1] ? ~op_a[k*16+:16]+1 : op_a[k*16+:16];
							  end
						 end

					   if((2**i)*8 == 8)
						 begin
							for(int k=0;k<8;k++)
							  begin
								 correct_result[k*8+:8] = op_a[(k+1)*8-1] ? ~op_a[k*8+:8]+1 : op_a[k*8+:8];
							  end
						 end
					   
					end
				  
				  #1;
				  $display("abs(%x) => %x, correct:%x  =>  %s",
						   op_a, op_abs, correct_result, 
						   op_abs === correct_result ? "equal" : "not equal" );
			   end
			 // $display("=============== passed ===============");
		  end
	 end // initial begin
endmodule // tb_add_vector
